/*
 * ECARX Technology Limited is the owner of the copyright and the trade secret of this software.
 * Without permission, no one has the right to obtain, disclose or use this software in any way.
 */

package com.ecarx.systemui.plugin.ui.dialog.calendar;

import androidx.annotation.NonNull;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;

public class CalendarEnData {

    private static final String TAG = "CalendarDataPluginEn";

    private static CalendarEnData calendarData;

    private CalendarEnData() {
    }

    public static synchronized CalendarEnData getInstance() {
        if (calendarData == null) {
            calendarData = new CalendarEnData();
        }
        return calendarData;
    }

    public CalendarEnData loadData() {
        Calendar currentDate = Calendar.getInstance();
        int curYear = currentDate.get(Calendar.YEAR);
        int curBaseMonth = currentDate.get(Calendar.MONTH);
        int curMonth = curBaseMonth + 1;
        int curDay = currentDate.get(Calendar.DATE);
        int week = currentDate.get(Calendar.DAY_OF_WEEK);
        int week_of_year = currentDate.get(Calendar.WEEK_OF_YEAR);

        if (calendarData.year == curYear &&
                calendarData.month == curMonth &&
                calendarData.day == curDay &&
                calendarData.calendarItemEntities != null &&
                calendarData.calendarItemEntities.size() > 0) {
            return calendarData;
        }
        calendarData.year = curYear;
        calendarData.month = curMonth;
        calendarData.day = curDay;
        calendarData.enStrWeek = getENWeek(week);
        calendarData.enStrMonthDay = String.format(Locale.getDefault(),
                "%s %d", getENMonth(month), calendarData.day);
        calendarData.strWeekNum = String.format(Locale.getDefault(),
                "Week %d", week_of_year);
        Calendar tempCal = Calendar.getInstance();
        tempCal.set(curYear, curBaseMonth, 1);
        int firstDayWeek = tempCal.get(Calendar.DAY_OF_WEEK);
        calendarData.monthDaysCount = LunarUtil.getMonthDaysCount(year, month);
        calendarData.beginIndex = getBeginIndex(firstDayWeek);
        calendarData.calendarItemEntities = getCalendarItems(calendarData.year, calendarData.month,
                calendarData.day, beginIndex, calendarData.monthDaysCount);
        return calendarData;
    }

    private List<CalendarItemEntity> getCalendarItems(int year, int month, int curDay, int beginIndex, int curtMonthTotalDays) {
        List<CalendarItemEntity> calendarItemEntities = new ArrayList<>();
        if (beginIndex > 0) {
            int[] lastYM = getLastMonthAndYear(year, month);
            int lastYear = lastYM[0];
            int lastMonth = lastYM[1];
            //上个月的天数
            int monthDaysCount = LunarUtil.getMonthDaysCount(lastYear, lastMonth);
            int nextBeginDay = monthDaysCount - beginIndex + 1;
            for (int i = 0; i < beginIndex; i++) {
                //这里主要添加上个月数据
                CalendarItemEntity calendarItemEntity = new CalendarItemEntity();
                calendarItemEntity.setIsLastOrNext(-1);
                int lastYlDay = nextBeginDay + i;
                calendarItemEntity.setYlDay(lastYlDay);
                calendarItemEntity.setCurrentDay(false);
                calendarItemEntities.add(calendarItemEntity);
            }
        }
        int currentDayIndex = 0;
        for (int i = 0; i < curtMonthTotalDays; i++) {
            CalendarItemEntity calendarItemEntity = new CalendarItemEntity();
            calendarItemEntity.setIsLastOrNext(0);
            int ylDay = i + 1;
            calendarItemEntity.setYlDay(ylDay);
            boolean isCurrentDay = (curDay == ylDay);
            calendarItemEntity.setCurrentDay(isCurrentDay);
            calendarItemEntities.add(calendarItemEntity);
            if (isCurrentDay) {
                currentDayIndex = calendarItemEntities.size() - 1;
            }
        }

        int size2 = calendarItemEntities.size();
        int mo = size2 % 7;
        int hasAddCount;
        if (mo == 0) {
            hasAddCount = mo;
        } else {
            hasAddCount = 7 - mo;
        }
        if (hasAddCount > 0) {
            for (int i = 0; i < hasAddCount; i++) {
                CalendarItemEntity calendarItemEntity = new CalendarItemEntity();
                calendarItemEntity.setIsLastOrNext(1);
                int nextYlDay = i + 1;
                calendarItemEntity.setYlDay(nextYlDay);
                calendarItemEntity.setCurrentDay(false);
                calendarItemEntities.add(calendarItemEntity);
            }
        }

        int totalSize = calendarItemEntities.size();
        int MAX_COUNT = 28;
        if (totalSize > MAX_COUNT) {
            if (totalSize <= 35) {
                //共5行
                if (currentDayIndex <= 17) {
                    return calendarItemEntities.subList(0, MAX_COUNT);
                } else {
                    return calendarItemEntities.subList(7, 35);
                }
            } else {
                //共6行
                if (currentDayIndex <= 20) {
                    return calendarItemEntities.subList(0, MAX_COUNT);
                } else {
                    return calendarItemEntities.subList(14, totalSize);
                }
            }
        }
        return calendarItemEntities;
    }

    //阳历年
    private int year;

    public int getYear() {
        return year;
    }

    //阳历yue
    private int month;

    //阳历日
    private int day;

    //英文月份
    private String enStrMonthDay;

    public String getEnStrMonthDay() {
        return enStrMonthDay;
    }

    //英文星期几
    private String enStrWeek;

    public String getEnStrWeek() {
        return enStrWeek;
    }

    //第几周
    private String strWeekNum;

    public String getStrWeekNum() {
        return strWeekNum;
    }

    //日历当月1号开始位置  星期一 index=0 ------ 星期天 index=6
    private int beginIndex;

    //阳历月天数
    private int monthDaysCount;

    private List<CalendarItemEntity> calendarItemEntities;

    public List<CalendarItemEntity> getCalendarItemEntities() {
        return calendarItemEntities;
    }

    public static class CalendarItemEntity {
        private int isLastOrNext; //-1-代表上月  0-代表当月   1-代表下月
        private int ylDay;
        private boolean isCurrentDay;

        public int getIsLastOrNext() {
            return isLastOrNext;
        }

        public void setIsLastOrNext(int isLastOrNext) {
            this.isLastOrNext = isLastOrNext;
        }

        public int getYlDay() {
            return ylDay;
        }

        public void setYlDay(int ylDay) {
            this.ylDay = ylDay;
        }

        public boolean isCurrentDay() {
            return isCurrentDay;
        }

        public void setCurrentDay(boolean currentDay) {
            isCurrentDay = currentDay;
        }


        @NonNull
        @Override
        public String toString() {
            return "\n CalendarItemEntity{" +
                    "\n    isLastOrNext=" + isLastOrNext +
                    "\n    ylDay=" + ylDay +
                    "\n    isCurrentDay=" + isCurrentDay +
                    "\n}";
        }
    }

    @NonNull
    @Override
    public String toString() {
        return "CalendarEnData{" +
                "\n enStrMonthDay='" + enStrMonthDay + '\'' +
                "\n enStrWeek='" + enStrWeek + '\'' +
                "\n strWeekNum='" + strWeekNum + '\'' +
                "\n beginIndex=" + beginIndex +
                "\n monthDaysCount=" + monthDaysCount +
                "\n calendarItemEntities=" + calendarItemEntities.toString() +
                "\n}";
    }


    private int[] getLastMonthAndYear(int year, int month) {
        int[] lastYM = new int[2];
        if (month == 1) {
            lastYM[0] = year - 1;
            lastYM[1] = 12;
        } else {
            lastYM[0] = year;
            lastYM[1] = month - 1;
        }
        return lastYM;
    }

    private int[] getNextMonthAndYear(int year, int month) {
        int[] nextYM = new int[2];
        if (month == 12) {
            nextYM[0] = year + 1;
            nextYM[1] = 1;
        } else {
            nextYM[0] = year;
            nextYM[1] = month + 1;
        }
        return nextYM;
    }


    private String getENWeek(int week) {
        switch (week) {
            case 1:
                return "Sunday";
            case 2:
                return "Monday";
            case 3:
                return "Tuesday";
            case 4:
                return "Wednesday";
            case 5:
                return "Thursday";
            case 6:
                return "Friday";
            default:
                return "Saturday";
        }
    }


    private String getENMonth(int month) {
        switch (month) {
            case 1:
                return "Jan";
            case 2:
                return "Feb";
            case 3:
                return "Mar";
            case 4:
                return "Apr";
            case 5:
                return "May";
            case 6:
                return "Jun";
            case 7:
                return "Jul";
            case 8:
                return "Aug";
            case 9:
                return "Sep";
            case 10:
                return "Oct";
            case 11:
                return "Nov";
            default:
                return "Dec";
        }
    }

    //不是角标，而是占位数量
    private int getBeginIndex(int euWeek) {
        switch (euWeek) {
            case 2:  //Monday
                return 0;
            case 3:  //Tuesday
                return 1;
            case 4:  //Wednesday
                return 2;
            case 5:  //Thursday
                return 3;
            case 6:  //Friday
                return 4;
            case 7:  //Saturday
                return 5;
            default: //Sunday
                return 6;
        }

    }
}
